#nullable enable

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PHMEE.CommonUtils;
using PHMEE.TDengineInfrastructure;

namespace PHMEE.EnergyEfficiency;

public sealed class FlowMeterTdRepository : BaseTdRepository, IFlowMeterTdRepository
{
    /// <summary>
    /// Flow Meter 位于能效库
    /// </summary>
    private const DbPrefixEnum DbPrefix = DbPrefixEnum.Ee;

    // /// <summary>
    // /// Flow Meter 约定好的超级表名
    // /// </summary>
    // private const string SuperTableName = "flowmeter";
    //
    // /// <summary>
    // /// 主机进油流量计子表名（在 XUE SONG 和 OP 船是主副机总进油流量计子表名）
    // /// </summary>
    // private const string MeInSubTableName = "fm_001";
    //
    // /// <summary>
    // /// 主机回油流量计子表名（在 XUE SONG 和 OP 船是主副机总回油流量计子表名）
    // /// </summary>
    // private const string MeOutSubTableName = "fm_002";
    //
    // /// <summary>
    // /// 副机进油流量计子表名
    // /// </summary>
    // private const string AeInSubTableName = "fm_003";
    //
    // /// <summary>
    // /// 副机回油流量计子表名
    // /// </summary>
    // private const string AeOutSubTableName = "fm_004";
    //
    // /// <summary>
    // /// 锅炉进油流量计子表名
    // /// </summary>
    // private const string BoInSubTableName = "fm_005";
    //
    // /// <summary>
    // /// 锅炉回油流量计子表名
    // /// </summary>
    // private const string BoOutSubTableName = "fm_006";
    
    private readonly ILogger<FlowMeterTdRepository> _logger;

    public FlowMeterTdRepository(IOptionsSnapshot<TDengineOptions> tdengineOptions, 
        ILogger<FlowMeterTdRepository> logger) : base(tdengineOptions)
    {
        _logger = logger;
    }

    // /// <summary>
    // /// 获取主机进油流量计数据集合（在 XUE SONG 和 OP 船是主副机总进油流量计）
    // /// </summary>
    // /// <param name="vesselId"></param>
    // /// <param name="startDateTimeUtc"></param>
    // /// <param name="endDateTimeUtc"></param>
    // /// <param name="tdOrder"></param>
    // /// <param name="tdRangeEdge"></param>
    // /// <returns></returns>
    // public Task<List<FlowMeterOilValueTde>> GetMeInListAsync(Guid vesselId, DateTime startDateTimeUtc,
    //     DateTime endDateTimeUtc, TdOrder tdOrder, TdRangeEdge tdRangeEdge)
    // {
    //     return GetListAsync(vesselId, startDateTimeUtc, endDateTimeUtc, MeInSubTableName, tdOrder, tdRangeEdge);
    // }
    //
    // /// <summary>
    // /// 获取主机回油流量计数据集合（在 XUE SONG 和 OP 船是主副机总回油流量计）
    // /// </summary>
    // /// <param name="vesselId"></param>
    // /// <param name="startDateTimeUtc"></param>
    // /// <param name="endDateTimeUtc"></param>
    // /// <param name="tdOrder"></param>
    // /// <param name="tdRangeEdge"></param>
    // /// <returns></returns>
    // public Task<List<FlowMeterOilValueTde>> GetMeOutListAsync(Guid vesselId, DateTime startDateTimeUtc,
    //     DateTime endDateTimeUtc, TdOrder tdOrder, TdRangeEdge tdRangeEdge)
    // {
    //     return GetListAsync(vesselId, startDateTimeUtc, endDateTimeUtc, MeOutSubTableName, tdOrder, tdRangeEdge);
    // }
    //
    // /// <summary>
    // /// 获取副机进油流量计数据集合
    // /// </summary>
    // /// <param name="vesselId"></param>
    // /// <param name="startDateTimeUtc"></param>
    // /// <param name="endDateTimeUtc"></param>
    // /// <param name="tdOrder"></param>
    // /// <param name="tdRangeEdge"></param>
    // /// <returns></returns>
    // public Task<List<FlowMeterOilValueTde>> GetAeInListAsync(Guid vesselId, DateTime startDateTimeUtc,
    //     DateTime endDateTimeUtc, TdOrder tdOrder, TdRangeEdge tdRangeEdge)
    // {
    //     return GetListAsync(vesselId, startDateTimeUtc, endDateTimeUtc, AeInSubTableName, tdOrder, tdRangeEdge);
    // }
    //
    // /// <summary>
    // /// 获取副机回油流量计数据集合
    // /// </summary>
    // /// <param name="vesselId"></param>
    // /// <param name="startDateTimeUtc"></param>
    // /// <param name="endDateTimeUtc"></param>
    // /// <param name="tdOrder"></param>
    // /// <param name="tdRangeEdge"></param>
    // /// <returns></returns>
    // public Task<List<FlowMeterOilValueTde>> GetAeOutListAsync(Guid vesselId, DateTime startDateTimeUtc,
    //     DateTime endDateTimeUtc, TdOrder tdOrder, TdRangeEdge tdRangeEdge)
    // {
    //     return GetListAsync(vesselId, startDateTimeUtc, endDateTimeUtc, AeOutSubTableName, tdOrder, tdRangeEdge);
    // }
    //
    // /// <summary>
    // /// 获取锅炉进油流量计数据集合
    // /// </summary>
    // /// <param name="vesselId"></param>
    // /// <param name="startDateTimeUtc"></param>
    // /// <param name="endDateTimeUtc"></param>
    // /// <param name="tdOrder"></param>
    // /// <param name="tdRangeEdge"></param>
    // /// <returns></returns>
    // public Task<List<FlowMeterOilValueTde>> GetBoInListAsync(Guid vesselId, DateTime startDateTimeUtc,
    //     DateTime endDateTimeUtc, TdOrder tdOrder, TdRangeEdge tdRangeEdge)
    // {
    //     return GetListAsync(vesselId, startDateTimeUtc, endDateTimeUtc, BoInSubTableName, tdOrder, tdRangeEdge);
    // }
    //
    // /// <summary>
    // /// 获取锅炉回油流量计数据集合
    // /// </summary>
    // /// <param name="vesselId"></param>
    // /// <param name="startDateTimeUtc"></param>
    // /// <param name="endDateTimeUtc"></param>
    // /// <param name="tdOrder"></param>
    // /// <param name="tdRangeEdge"></param>
    // /// <returns></returns>
    // public Task<List<FlowMeterOilValueTde>> GetBoOutListAsync(Guid vesselId, DateTime startDateTimeUtc,
    //     DateTime endDateTimeUtc, TdOrder tdOrder, TdRangeEdge tdRangeEdge)
    // {
    //     return GetListAsync(vesselId, startDateTimeUtc, endDateTimeUtc, BoOutSubTableName, tdOrder, tdRangeEdge);
    // }

    public async Task<List<FlowMeterOilValueTde>> GetListAsync(Guid vesselId, DateTime startDateTimeUtc,
        DateTime endDateTimeUtc, string flowMeterName, TdOrder tdOrder, TdRangeEdge tdRangeEdge)
    {
        try
        {
            string dbName = PhmeeConst.GetDbName(DbPrefix, vesselId);
            string order = GetOrder(tdOrder);

            string tsRangeWhere = tdRangeEdge switch
            {
                TdRangeEdge.CloseOpen =>
                    $"ts >= '{startDateTimeUtc.ToFormattedUtcString()}' and ts < '{endDateTimeUtc.ToFormattedUtcString()}'",
                TdRangeEdge.OpenClose =>
                    $"ts > '{startDateTimeUtc.ToFormattedUtcString()}' and ts <= '{endDateTimeUtc.ToFormattedUtcString()}'",
                _ => throw new ArgumentOutOfRangeException(nameof(tdRangeEdge), tdRangeEdge, "未知的时间范围边缘设定")
            };

            await using var command = TDConnection.CreateCommand();

            command.CommandText =
                $"select ts, oil_value, fuel_type from {dbName}.{flowMeterName} where {tsRangeWhere} order by ts {order};";

            await using var reader = await command.ExecuteReaderAsync();

            var list = new List<FlowMeterOilValueTde>();

            while (await reader.ReadAsync())
            {
                list.Add(new FlowMeterOilValueTde
                {
                    Ts = GetDateTimeUtc("ts", reader),
                    OilValue = reader.GetValue(reader.GetOrdinal("oil_value")) as float? ?? default,
                    FuelType = (FuelType)reader.GetInt32(reader.GetOrdinal("fuel_type"))
                });
            }

            return list;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"TDengine 仓储: {nameof(FlowMeterTdRepository)}.{nameof(GetListAsync)} 失败");
            throw new TDengineRepositoryException(vesselId, null, startDateTimeUtc, endDateTimeUtc, $"根据时间范围 {tdRangeEdge} 查询流量计 oil_value {tdOrder} 数据失败", ex);
        }
    }
    
    // public Task<FlowMeterOilValueTde?> GetMeInLatestFuelOilValueAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelOilValueAsync(vesselId, dateTimeUtc, MeInSubTableName);
    // }
    //
    // public Task<FlowMeterOilValueTde?> GetMeOutLatestFuelOilValueAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelOilValueAsync(vesselId, dateTimeUtc, MeOutSubTableName);
    // }
    //
    // public Task<FlowMeterOilValueTde?> GetAeInLatestFuelOilValueAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelOilValueAsync(vesselId, dateTimeUtc, AeInSubTableName);
    // }
    //
    // public Task<FlowMeterOilValueTde?> GetAeOutLatestFuelOilValueAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelOilValueAsync(vesselId, dateTimeUtc, AeOutSubTableName);
    // }
    //
    // public Task<FlowMeterOilValueTde?> GetBoInLatestFuelOilValueAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelOilValueAsync(vesselId, dateTimeUtc, BoInSubTableName);
    // }
    //
    // public Task<FlowMeterOilValueTde?> GetBoOutLatestFuelOilValueAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelOilValueAsync(vesselId, dateTimeUtc, BoOutSubTableName);
    // }
    
    public async Task<FlowMeterOilValueTde?> GetLatestFuelOilValueAsync(Guid vesselId, DateTime dateTimeUtc, string flowMeterName)
    {
        try
        {
            string dbName = PhmeeConst.GetDbName(DbPrefix, vesselId);

            await using var command = TDConnection.CreateCommand();

            command.CommandText =
                $"select ts, oil_value, fuel_type from {dbName}.{flowMeterName} where ts <= '{dateTimeUtc.ToFormattedUtcString()}' order by ts desc limit 1;";

            await using var reader = await command.ExecuteReaderAsync();

            if (await reader.ReadAsync())
            {
                return new FlowMeterOilValueTde
                {
                    Ts = GetDateTimeUtc("ts", reader),
                    OilValue = reader.GetValue(reader.GetOrdinal("oil_value")) as float? ?? default,
                    FuelType = (FuelType)reader.GetInt32(reader.GetOrdinal("fuel_type"))
                };
            }

            return null;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"TDengine 仓储: {nameof(FlowMeterTdRepository)}.{nameof(GetLatestFuelOilValueAsync)} 失败");
            throw new TDengineRepositoryException(vesselId, null, dateTimeUtc, null, "查询最新油品流量计数据失败", ex);
        }
    }
    
    // public Task<FuelType?> GetMeLatestFuelTypeAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelTypeAsync(vesselId, dateTimeUtc, MeInSubTableName);
    // }
    //
    // public Task<FuelType?> GetAeLatestFuelTypeAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelTypeAsync(vesselId, dateTimeUtc, AeInSubTableName);
    // }
    //
    // public Task<FuelType?> GetBoLatestFuelTypeAsync(Guid vesselId, DateTime dateTimeUtc)
    // {
    //     return GetLatestFuelTypeAsync(vesselId, dateTimeUtc, BoInSubTableName);
    // }

    // /// <summary>
    // /// 获取最新油品
    // /// </summary>
    // /// <param name="vesselId"></param>
    // /// <param name="dateTimeUtc"></param>
    // /// <param name="flowMeterName"></param>
    // /// <returns></returns>
    // /// <exception cref="TDengineRepositoryException"></exception>
    // public async Task<FuelType?> GetLatestFuelTypeAsync(Guid vesselId, DateTime dateTimeUtc, string flowMeterName)
    // {
    //     try
    //     {
    //         string dbName = PhmeeConst.GetDbName(DbPrefix, vesselId);
    //
    //         await using var command = TDConnection.CreateCommand();
    //
    //         command.CommandText =
    //             $"select fuel_type from {dbName}.{flowMeterName} where ts <= '{dateTimeUtc.ToFormattedUtcString()}' order by ts desc limit 1;";
    //
    //         await using var reader = await command.ExecuteReaderAsync();
    //
    //         if (await reader.ReadAsync())
    //         {
    //             var fuelTypeObj = reader.GetValue(reader.GetOrdinal("fuel_type"));
    //             if (fuelTypeObj != DBNull.Value)
    //             {
    //                 return (FuelType)reader.GetInt32(reader.GetOrdinal("fuel_type"));
    //             }
    //         }
    //
    //         return null;
    //     }
    //     catch (Exception ex)
    //     {
    //         _logger.LogError(ex, $"TDengine 仓储: {nameof(FlowMeterTdRepository)}.{nameof(GetLatestFuelTypeAsync)} 失败");
    //         throw new TDengineRepositoryException(vesselId, null, dateTimeUtc, null, "查询最新燃油类型失败", ex);
    //     }
    // }

    // public async Task<FuelFlowMeterConfig> GetFlowMeterConfigAsync(Guid vesselId)
    // {
    //     try
    //     {
    //         string dbName = PhmeeConst.GetDbName(DbPrefix, vesselId);
    //
    //         await using var command = TDConnection.CreateCommand();
    //
    //         command.CommandText = $"select distinct tbname from {dbName}.{SuperTableName} where tbname IN ('{MeInSubTableName}','{MeOutSubTableName}','{AeInSubTableName}','{AeOutSubTableName}','{BoInSubTableName}','{BoOutSubTableName}');";
    //
    //         await using var reader = await command.ExecuteReaderAsync();
    //
    //         var config = new FuelFlowMeterConfig();
    //
    //         while (await reader.ReadAsync())
    //         {
    //             var tbname = reader.GetString(reader.GetOrdinal("tbname"));
    //
    //             switch (tbname)
    //             {
    //                 case MeInSubTableName:
    //                     config.MEInlet = true;
    //                     break;
    //                 case MeOutSubTableName:
    //                     config.MEOutlet = true;
    //                     break;
    //                 case AeInSubTableName:
    //                     config.AEInlet = true;
    //                     break;
    //                 case AeOutSubTableName:
    //                     config.AEOutlet = true;
    //                     break;
    //                 case BoInSubTableName:
    //                     config.BoilerInlet = true;
    //                     break;
    //                 case BoOutSubTableName:
    //                     config.BoilerOutlet = true;
    //                     break;
    //             }
    //         }
    //
    //         return config;
    //     }
    //     catch (Exception ex)
    //     {
    //         _logger.LogError(ex, $"TDengine 仓储: {nameof(FlowMeterTdRepository)}.{nameof(GetFlowMeterConfigAsync)} 失败");
    //         throw new TDengineRepositoryException(vesselId, null, null, null, "查询流量计配置失败", ex);
    //     }
    // }
}